package com.asen.libcommon.http

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.liveData
import com.asen.libcommon.http.info.HttpListResult
import com.asen.libcommon.http.info.HttpResult
import com.asen.libcommon.http.livedata.ApiEmptyResponse
import com.asen.libcommon.http.livedata.ApiErrorResponse
import com.asen.libcommon.http.livedata.ApiSuccessResponse
import com.asen.libcommon.http.livedata.LiveDataResponse
import com.orhanobut.logger.Logger
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

/**
 * @date   : 2021/3/3
 * @author : asenLiang
 * @e-mail : liangAisiSen@163.com
 * @desc   : 网络请求框架封装
 */

// TODO：用 moshi 网络请求 携程封装,可以多个接口一起请求
fun CoroutineScope.extMoShiRequest(
    onStart: (suspend () -> Unit)? = null,
    onEnd: (suspend () -> Unit)? = null
) {
    launch {
        try {
            Logger.w("请求开始携程")
            onStart?.invoke()
        } catch (e: Throwable) { // 异常处理 TODO:HttpException/SocketTimeoutException/SocketException/UnknownHostException/SSLException
            Logger.e("请求失败携程 -->> ${e.cause?.message}")
            onEnd?.invoke()
        }
        onEnd?.invoke()
    }
}

// todo：携程封装回调LiveData参数，配合 moShiRequest() 方法的 onStart() 使用
fun <T> CoroutineScope.extLiveDataHttp(data: HttpListResult<T>): LiveData<MutableList<T>> {
    return liveData(this.coroutineContext) {
        emit(data.result)
    }
}

// todo：携程封装回调LiveData参数，配合 moShiRequest() 方法的 onStart() 使用
 fun <T> CoroutineScope.extLiveDataHttp(data: HttpResult<T>): LiveData<T> {
    return liveData(this.coroutineContext) {
        emit(data.result)
    }
}

// TODO：用 rx 网络请求封装
fun <T> Observable<T>.extRxRequest(
    onSuccess: ((T) -> Unit)? = null,
    onStart: (() -> Unit)? = null,
    onEnd: (() -> Unit)? = null
): Disposable? {
    onStart?.invoke()
    return subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            {
                Logger.e("Rx成功")
                onSuccess?.invoke(it)
            },
            // 异常处理 TODO:HttpException/SocketTimeoutException/SocketException/UnknownHostException/SSLException
            {
                Logger.e("Rx失败 >> ${it.message}")
                onEnd?.invoke()
            },
            {
                Logger.e("Rx完成")
                onEnd?.invoke()
            }
        )
}

// TODO：用 liveData 网络请求封装
fun <T> LiveData<LiveDataResponse<T>>.extLiveDataRequest(
    owner: LifecycleOwner,
    onSuccess: ((T) -> Unit)? = null,
    onStart: (() -> Unit)? = null,
    onEnd: (() -> Unit)? = null
) {
    onStart?.invoke()
    try {
        observe(owner, Observer {
            when (it) {
                is ApiSuccessResponse -> {
                    Logger.w("成功LiveData")
                    onSuccess?.invoke(it.body)
                    onEnd?.invoke()
                }
                is ApiEmptyResponse -> {
                    Logger.w("成功1LiveData")
                    onEnd?.invoke()
                }
                is ApiErrorResponse -> {
                    Logger.w("失败LiveData >> ${it.details}")
                    onEnd?.invoke()
                }
            }
        })
    } catch (e: Exception) {
        onEnd?.invoke()
    }
}